home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1995 #5 & #6
/
Amiga Plus CD - 1995 - No. 5 and 6.iso
/
pd
/
netz
/
term
/
extras
/
source
/
term-source.lha
/
CaptureParser.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-07
|
11KB
|
580 lines
/*
** CaptureParser.c
**
** Capture filter parser
**
** Copyright © 1990-1995 by Olaf `Olsen' Barthel
** All Rights Reserved
*/
#include "termGlobal.h"
typedef BOOL (* SPECIAL_JUMP)(VOID);
typedef BOOL (* __regargs ABORT_JUMP)(register WORD Char);
STATIC BOOL SpecialBackspace(VOID);
STATIC BOOL SpecialReturn(VOID);
STATIC BOOL SpecialTab(VOID);
STATIC BOOL SpecialEsc(VOID);
STATIC BOOL SpecialCSI(VOID);
STATIC BOOL AbortCancel(VOID);
STATIC BOOL AbortEsc(VOID);
STATIC BOOL AbortCSI(VOID);
STATIC BOOL __regargs LocalParse(register WORD c);
/* How many characters we will keep in the scan buffer. */
#define MAX_SCAN_SIZE 256
STATIC struct { UBYTE Key; SPECIAL_JUMP Routine; } LocalSpecialKeys[] =
{
'\b', (SPECIAL_JUMP)SpecialBackspace, /* Erase a character. */
'\r', (SPECIAL_JUMP)SpecialReturn, /* Carriage return. */
'\t', (SPECIAL_JUMP)SpecialTab, /* Move to next tab stop. */
27, (SPECIAL_JUMP)SpecialEsc, /* Start new control sequence. */
155, (SPECIAL_JUMP)SpecialCSI /* Start new control sequence. */
};
STATIC SPECIAL_JUMP *LocalSpecialTable;
STATIC ABORT_JUMP *LocalAbortTable;
STATIC STRPTR Arnie = NULL;
STATIC WORD CharsInBuffer = 0,
ScanStep = 0;
STATIC BOOL LocalInSequence = FALSE;
STATIC UBYTE __far SaveBuffer[MAX_SCAN_SIZE + 1];
STATIC UBYTE __far LocalLineBuffer[BUFFER_LINE_MAX + 1];
STATIC WORD LocalLineLen,
LocalLineIndex;
STATIC BOOL
SpecialBackspace()
{
if(LocalLineIndex)
LocalLineIndex--;
return(FALSE);
}
STATIC BOOL
SpecialReturn()
{
LocalLineIndex = 0;
return(FALSE);
}
STATIC BOOL
SpecialTab()
{
WORD Index = (LocalLineIndex + 7) & ~8;
if(Index > LocalLineLen)
memset(&LocalLineBuffer[LocalLineLen],' ',Index - LocalLineLen);
LocalLineIndex = Index;
if(Index > LocalLineLen)
LocalLineLen = Index;
return(FALSE);
}
STATIC BOOL
SpecialEsc()
{
return(TRUE);
}
STATIC BOOL
SpecialCSI()
{
return(LocalParse('['));
}
STATIC BOOL
AbortCancel()
{
LocalInSequence = FALSE;
CharsInBuffer = 0;
ScanStep = 0;
return(FALSE);
}
STATIC BOOL
AbortEsc()
{
AbortCancel();
LocalInSequence = TRUE;
return(TRUE);
}
STATIC BOOL
AbortCSI()
{
AbortCancel();
LocalInSequence = TRUE;
return(LocalParse('['));
}
/* LocalParse(UBYTE c):
*
* Input: A character to be passed through the ANSI code
* parser.
*
* Output: FALSE if input characters did form a valid ANSI
* control sequence or if input characters did not
* form an ANSI control sequence at all.
*
* TRUE if input characters did possibly introduce
* a valid ANSI control sequence.
*/
STATIC BOOL __regargs
LocalParse(register WORD c)
{
/* ScanStep = 0: This is the first character
* to introduce a control sequence.
*/
if(!ScanStep)
{
register WORD i;
/* Scan all available codes and try to find
* a match.
*/
for(i = 0 ; i < NumCodes ; i++)
{
/* This character may introduce a
* control sequence.
*/
if(ANSICode[i] . FirstChar == c)
{
/* If this is a single
* character control sequence
* call the approriate function
* and exit immediately.
*/
if(ANSICode[i] . ExactSize == 1)
{
CharsInBuffer = ScanStep = 0;
return(FALSE);
}
else
{
/* The length of this control
* sequence is greater than
* a single character. Save
* the input character and
* return.
*/
ScanStep = i;
SaveBuffer[CharsInBuffer++] = c;
/* Where to stop. */
Arnie = ANSICode[i] . Terminator;
return(TRUE);
}
}
}
}
else
{
if(CharsInBuffer < MAX_SCAN_SIZE)
{
if(Arnie)
{
register WORD i;
/* Scan the remaining codes for a match. */
for(i = ScanStep ; i < NumCodes ; i++)
{
/* This sequence begins with the
* same character the parser was
* initialized with, so let's take
* a look at it.
*/
if(ANSICode[i] . FirstChar == SaveBuffer[0])
{
/* This character is supposed to
* terminate the sequence, so exit.
*/
if(Arnie[c])
{
CharsInBuffer = ScanStep = 0;
Arnie = NULL;
return(FALSE);
}
else
{
/* If this character is part of
* a legal sequence store it
* and return.
*/
if(ANSICode[i] . Match[c])
{
ScanStep = i;
SaveBuffer[CharsInBuffer++] = c;
return(TRUE);
}
}
}
}
}
else
{
register WORD i;
for(i = ScanStep ; i < NumCodes ; i++)
{
/* This sequence begins with the
* same character the parser was
* initialized with, so let's take
* a look at it.
*/
if(ANSICode[i] . FirstChar == SaveBuffer[0])
{
/* This character is supposed to
* terminate the sequence, so exit.
*/
if(ANSICode[i] . LastChar == c)
{
CharsInBuffer = ScanStep = 0;
return(FALSE);
}
else
{
/* If this character is part of
* a legal sequence store it
* and return.
*/
if(ANSICode[i] . Match[c])
{
ScanStep = i;
SaveBuffer[CharsInBuffer++] = c;
return(TRUE);
}
}
}
}
}
}
}
/* Return failure. */
CharsInBuffer = ScanStep = 0;
Arnie = NULL;
return(FALSE);
}
VOID
CaptureParserExit()
{
if(LocalSpecialTable)
{
FreeVecPooled(LocalSpecialTable);
LocalSpecialTable = NULL;
}
if(LocalAbortTable)
{
FreeVecPooled(LocalAbortTable);
LocalAbortTable = NULL;
}
}
BOOL
CaptureParserInit()
{
if(LocalSpecialTable = (SPECIAL_JUMP *)AllocVecPooled(256 * sizeof(SPECIAL_JUMP),MEMF_ANY | MEMF_CLEAR))
{
if(LocalAbortTable = (ABORT_JUMP *)AllocVecPooled(256 * sizeof(ABORT_JUMP),MEMF_ANY | MEMF_CLEAR))
{
WORD i;
for(i = 0 ; i < NumElements(LocalSpecialKeys) ; i++)
LocalSpecialTable[LocalSpecialKeys[i] . Key] = LocalSpecialKeys[i] . Routine;
for(i = 0 ; i < 256 ; i++)
{
switch(AbortMap[i])
{
case 0: LocalAbortTable[i] = LocalParse;
break;
case 1: LocalAbortTable[i] = (ABORT_JUMP)AbortCancel;
break;
case 2: LocalAbortTable[i] = (ABORT_JUMP)AbortEsc;
break;
case 3: LocalAbortTable[i] = (ABORT_JUMP)AbortCSI;
break;
}
}
return(TRUE);
}
}
return(FALSE);
}
VOID __regargs
CaptureParser(register STRPTR Buffer,register LONG Size,register COPTR OutputRoutine)
{
if(Size > 0)
{
register WORD c;
if(Config -> SerialConfig -> StripBit8)
{
if(LocalInSequence)
{
register BYTE Result;
do
{
c = *Buffer++ & 0x7F;
Result = (*LocalAbortTable[c])(c);
}
while(--Size > 0 && Result);
LocalInSequence = Result;
}
if(Size > 0)
{
register LONG BufferWidth = Config -> CaptureConfig -> BufferWidth - 1;
if(Config -> TerminalConfig -> FontMode == FONT_STANDARD)
{
do
{
c = (*Buffer++) & 0x7F;
if(LocalInSequence)
LocalInSequence = (*LocalAbortTable[c])(c);
else
{
if(LocalSpecialTable[c])
LocalInSequence = (*LocalSpecialTable[c])();
else
{
if(c == '\n' || c == '\f' || c == '\v')
{
(*OutputRoutine)(LocalLineBuffer,LocalLineLen);
LocalLineIndex = LocalLineLen = 0;
}
else
{
if(IsGlyph[c])
{
LocalLineBuffer[LocalLineIndex++] = c;
if(LocalLineIndex > LocalLineLen)
LocalLineLen = LocalLineIndex;
if(LocalLineLen > BufferWidth)
{
(*OutputRoutine)(LocalLineBuffer,LocalLineLen);
LocalLineIndex = LocalLineLen = 0;
}
}
}
}
}
}
while(--Size > 0);
}
else
{
do
{
c = (*Buffer++) & 0x7F;
if(LocalInSequence)
LocalInSequence = (*LocalAbortTable[c])(c);
else
{
if(LocalSpecialTable[c])
LocalInSequence = (*LocalSpecialTable[c])();
else
{
if(c == '\n' || c == '\f' || c == '\v')
{
(*OutputRoutine)(LocalLineBuffer,LocalLineLen);
LocalLineIndex = LocalLineLen = 0;
}
else
{
if(c)
{
LocalLineBuffer[LocalLineIndex++] = c;
if(LocalLineIndex > LocalLineLen)
LocalLineLen = LocalLineIndex;
if(LocalLineLen > BufferWidth)
{
(*OutputRoutine)(LocalLineBuffer,LocalLineLen);
LocalLineIndex = LocalLineLen = 0;
}
}
}
}
}
}
while(--Size > 0);
}
}
}
else
{
if(LocalInSequence)
{
register BYTE Result;
do
{
c = *Buffer++;
Result = (*LocalAbortTable[c])(c);
}
while(--Size > 0 && Result);
LocalInSequence = Result;
}
if(Size > 0)
{
register LONG BufferWidth = Config -> CaptureConfig -> BufferWidth - 1;
if(Config -> TerminalConfig -> FontMode == FONT_STANDARD)
{
do
{
c = *Buffer++;
if(LocalInSequence)
LocalInSequence = (*LocalAbortTable[c])(c);
else
{
if(LocalSpecialTable[c])
LocalInSequence = (*LocalSpecialTable[c])();
else
{
if(c == '\n' || c == '\f' || c == '\v')
{
(*OutputRoutine)(LocalLineBuffer,LocalLineLen);
LocalLineIndex = LocalLineLen = 0;
}
else
{
if(IsGlyph[c])
{
LocalLineBuffer[LocalLineIndex++] = c;
if(LocalLineIndex > LocalLineLen)
LocalLineLen = LocalLineIndex;
if(LocalLineLen > BufferWidth)
{
(*OutputRoutine)(LocalLineBuffer,LocalLineLen);
LocalLineIndex = LocalLineLen = 0;
}
}
}
}
}
}
while(--Size > 0);
}
else
{
do
{
c = *Buffer++;
if(LocalInSequence)
LocalInSequence = (*LocalAbortTable[c])(c);
else
{
if(LocalSpecialTable[c])
LocalInSequence = (*LocalSpecialTable[c])();
else
{
if(c == '\n' || c == '\f' || c == '\v')
{
(*OutputRoutine)(LocalLineBuffer,LocalLineLen);
LocalLineIndex = LocalLineLen = 0;
}
else
{
if(c)
{
LocalLineBuffer[LocalLineIndex++] = c;
if(LocalLineIndex > LocalLineLen)
LocalLineLen = LocalLineIndex;
if(LocalLineLen > BufferWidth)
{
(*OutputRoutine)(LocalLineBuffer,LocalLineLen);
LocalLineIndex = LocalLineLen = 0;
}
}
}
}
}
}
while(--Size > 0);
}
}
}
}
}